<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>我想知道多线程如何停止 | HankChan&#39;s Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="记录小小，看的是《Java Multi-Thread Programming》在学习多线程的过程中，很多时候对这个如何停止多线程，或者说让他中断、等待等方面还很浅薄。甚至可以说还没有完全领会多线程设计的原理是怎么一回事。 在学到多线程如何停止的时候，主要看到有几种停止多线程的方式。做个现在这个阶段的我对这方面的学习理解和记录吧！ 1.停止不了的线程Thread中提供了一个 interrupt()">
<meta property="og:type" content="article">
<meta property="og:title" content="我想知道多线程如何停止">
<meta property="og:url" content="http://hexo.hankchan.cn/2016/08/06/e6-88-91-e6-83-b3-e7-9f-a5-e9-81-93-e5-a4-9a-e7-ba-bf-e7-a8-8b-e5-a6-82-e4-bd-95-e5-81-9c-e6-ad-a2/index.html">
<meta property="og:site_name" content="HankChan&#39;s Blog">
<meta property="og:description" content="记录小小，看的是《Java Multi-Thread Programming》在学习多线程的过程中，很多时候对这个如何停止多线程，或者说让他中断、等待等方面还很浅薄。甚至可以说还没有完全领会多线程设计的原理是怎么一回事。 在学到多线程如何停止的时候，主要看到有几种停止多线程的方式。做个现在这个阶段的我对这方面的学习理解和记录吧！ 1.停止不了的线程Thread中提供了一个 interrupt()">
<meta property="og:updated_time" content="2017-05-26T02:13:23.615Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="我想知道多线程如何停止">
<meta name="twitter:description" content="记录小小，看的是《Java Multi-Thread Programming》在学习多线程的过程中，很多时候对这个如何停止多线程，或者说让他中断、等待等方面还很浅薄。甚至可以说还没有完全领会多线程设计的原理是怎么一回事。 在学到多线程如何停止的时候，主要看到有几种停止多线程的方式。做个现在这个阶段的我对这方面的学习理解和记录吧！ 1.停止不了的线程Thread中提供了一个 interrupt()">
  
    <link rel="alternate" href="/atom.xml" title="HankChan&#39;s Blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
  

</head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">HankChan&#39;s Blog</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">生活就像海洋</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="搜索"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://hexo.hankchan.cn"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-e6-88-91-e6-83-b3-e7-9f-a5-e9-81-93-e5-a4-9a-e7-ba-bf-e7-a8-8b-e5-a6-82-e4-bd-95-e5-81-9c-e6-ad-a2" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2016/08/06/e6-88-91-e6-83-b3-e7-9f-a5-e9-81-93-e5-a4-9a-e7-ba-bf-e7-a8-8b-e5-a6-82-e4-bd-95-e5-81-9c-e6-ad-a2/" class="article-date">
  <time datetime="2016-08-06T12:00:17.000Z" itemprop="datePublished">2016-08-06</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/未分类/">未分类</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      我想知道多线程如何停止
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="记录小小，看的是《Java-Multi-Thread-Programming》"><a href="#记录小小，看的是《Java-Multi-Thread-Programming》" class="headerlink" title="记录小小，看的是《Java Multi-Thread Programming》"></a>记录小小，看的是《Java Multi-Thread Programming》</h3><p>在学习多线程的过程中，很多时候对这个如何停止多线程，或者说让他中断、等待等方面还很浅薄。甚至可以说还没有完全领会多线程设计的原理是怎么一回事。</p>
<p>在学到多线程如何停止的时候，主要看到有几种停止多线程的方式。做个现在这个阶段的我对这方面的学习理解和记录吧！</p>
<h4 id="1-停止不了的线程"><a href="#1-停止不了的线程" class="headerlink" title="1.停止不了的线程"></a><a href="https://github.com/hank0chan/blog/blob/master/201608/%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2.md#1停止不了的线程" target="_blank" rel="external"></a>1.停止不了的线程</h4><p>Thread中提供了一个 interrupt() 方法来停止线程，但是实际上它并不像是循环语句中使用break那样，马上中断。本质上，只是在当前的线程中打了一个停止的标识，并不是真的停止线程！</p>
<h4 id="2-判断线程是否是停止状态"><a href="#2-判断线程是否是停止状态" class="headerlink" title="2.判断线程是否是停止状态"></a><a href="https://github.com/hank0chan/blog/blob/master/201608/%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2.md#2判断线程是否是停止状态" target="_blank" rel="external"></a>2.判断线程是否是停止状态</h4><p>Thread提供了两个方法： 1. this.interrupted() = 测试当前线程是否已经中断 2. this.isInterrupted() = 测试线程是否已经中断</p>
<p>其源代码声明如下：</p>
<pre><code>public static boolean interrupted() //

public boolean isInterrupted() //
`&lt;/pre&gt;
这一部分太坑爹，不贴我自己的示例代码了！

#### [](https://github.com/hank0chan/blog/blob/master/201608/%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2.md#3能停止的线程--异常法优化后可以真正停止的呀)3.能停止的线程--异常法（优化后可以真正停止的呀！）

我们可以利用线程状态的判断来选择跳出循环，达到目的。 选择在for循环中判断this.interrupted()，从而考虑利用break跳出循环是个好办法。如下方代码中的被屏蔽的代码块，就是此方法。

但是该方法存在一个问题，如果代码出现在for循环之外，你会发现就算是执行了interrupt()方法同样不能阻止for循环外的代码的运行！所以我们需要优化呀！
&lt;pre&gt;`public class MyThread extends Thread {

    /**
     * 优化 语句继续运行 的解决方法：
     */
    @SuppressWarnings(&quot;static-access&quot;)
    @Override
    public void run() {
        super.run();
        try {
            for(int i = 0; i &amp;lt; 500000; i++) {
                if(this.interrupted()) {
                    System.out.println(&quot;已经停止状态！准备退出了！&quot;);
                    throw new InterruptedException();
                }
                System.out.println(&quot;执行中, i = &quot; + (i + 1));
            }
            System.out.println(&quot;我是在for循环之后的代码，现在你的this.interrupted是ture所以跳出循环执行了我。。&quot;);
            System.out.println(&quot;注意：===&amp;gt;&amp;gt;如果你看到了我，说明并非执行了interrupt()方法就可以让线程结束&quot;);

        } catch (InterruptedException e) {
            System.out.println(&quot;进到MyThread.java类run方法中的catch中了。。。&quot;);
            e.printStackTrace();
        }
    }

    /*@SuppressWarnings(&quot;static-access&quot;)
    @Override
    public void run() {
        super.run();
        for(int i = 0; i &amp;lt; 500000; i++) {
            if(this.interrupted()) {
                System.out.println(&quot;已经停止状态！准备退出了！&quot;);
                break;
            }
            System.out.println(&quot;执行中, i = &quot; + (i + 1));
        }
        System.out.println(&quot;我是在for循环之后的代码，现在你的this.interrupted是ture所以跳出循环执行了我。。&quot;);
        System.out.println(&quot;注意：===&amp;gt;&amp;gt;如果你看到了我，说明并非执行了interrupt()方法就可以让线程结束&quot;);
    }*/ 
}

@Test
public void testMyThread() {
    try {
        MyThread thread = new MyThread();
        thread.start();
        Thread.sleep(2000);
        thread.interrupt();
    } catch (InterruptedException e) {
        System.out.println(&quot;main &apos;s catch..&quot;);
        e.printStackTrace();
    }
    System.out.println(&quot;end!&quot;);
}
`&lt;/pre&gt;
运行结果如下： [![](https://camo.githubusercontent.com/e612170ae84892c422ad74ee3373a9347db7f239/687474703a2f2f692e696d6775722e636f6d2f516a436f6b69492e706e67)](https://camo.githubusercontent.com/e612170ae84892c422ad74ee3373a9347db7f239/687474703a2f2f692e696d6775722e636f6d2f516a436f6b69492e706e67)

#### [](https://github.com/hank0chan/blog/blob/master/201608/%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2.md#4-在沉睡中停止)4\. 在沉睡中停止！！

我对sleep()这个破玩意儿一定很迷糊！！ 来试试用sleep()状态下停止线程的效果吧！
&lt;pre&gt;`public class Mythread1 extends Thread {

    @Override
    public void run() {
        super.run();
        try {
            System.out.println(&quot;run start.....&quot;);
            Thread.sleep(200000);
            System.out.println(&quot;run end.....&quot;);
        } catch (InterruptedException e) {
            System.out.println(&quot;在沉睡中被停止。。进入到catch了！&quot; + this.isInterrupted());
            e.printStackTrace();
        }
    }
}

@Test
public void testMyThread1() {
    try {
        Mythread1 th = new Mythread1();
        th.start();
        Thread.sleep(200);
        th.interrupt();
    } catch (InterruptedException e) {
        System.out.println(&quot;main &apos;s catch...&quot;);
        e.printStackTrace();
    }
    System.out.println(&quot;end!&quot;);
}
`&lt;/pre&gt;
我的理解是：可以看到，在主线程执行200ms后就结束方法，而在子线程中需要200000ms以上的时间，所以在200ms时子线程捕获到一个主线程的中断异常，也跟着中断了线程。

#### [](https://github.com/hank0chan/blog/blob/master/201608/%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2.md#5-stop方法弃用)5\. stop()方法，弃用！！

#### [](https://github.com/hank0chan/blog/blob/master/201608/%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2.md#6-使用return停止线程)6\. 使用return停止线程

使用interrupt()方法和return结合同样可以达到效果！ public class MyThread2 extends Thread {
&lt;pre&gt;`    @Override
    public void run() {
        super.run(); //对于这个我还是有点懵
        while(true) {
            if(this.isInterrupted()) {
                System.out.println(&quot;停止了！！&quot;);
                return;
            }
            System.out.println(&quot;timer:&quot; + System.currentTimeMillis());
        }
    }

}

@Test
public void testMyThread2() throws InterruptedException {
    MyThread2 t = new MyThread2();
    t.start();
    Thread.sleep(100);
    t.interrupt();
}
</code></pre>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://hexo.hankchan.cn/2016/08/06/e6-88-91-e6-83-b3-e7-9f-a5-e9-81-93-e5-a4-9a-e7-ba-bf-e7-a8-8b-e5-a6-82-e4-bd-95-e5-81-9c-e6-ad-a2/" data-id="cj359k3x9000kfwv7p3ywizc8" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2016/08/09/e5-b0-81-e8-a3-85-e4-bd-bf-e7-94-a8completionservice-e5-b9-b6-e5-8f-91-e5-a4-84-e7-90-86-e4-bb-bb-e5-8a-a1/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          封装使用CompletionService并发处理任务
        
      </div>
    </a>
  
  
    <a href="/2016/08/05/e5-af-b9springmvcmybatis-e5-9c-a8-e9-a1-b9-e7-9b-ae-e4-b8-ad-e4-bd-bf-e7-94-a8-e7-9a-84-e5-ad-a6-e4-b9-a0-e6-80-9d-e8-80-83/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">对SpringMVC+Mybatis在项目中使用的学习思考</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Docker/">Docker</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Eclipse/">Eclipse</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/Eclipse/Mybatis/">Mybatis</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Eclipse/Spring/">Spring</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Eclipse/分布式/">分布式</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/Git/">Git</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Linux/">Linux</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/Linux/Nginx/">Nginx</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/Mybatis/">Mybatis</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/Mybatis/Spring/">Spring</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/Mybatis/Spring/SpringMVC/">SpringMVC</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/Mybatis/SpringMVC/">SpringMVC</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/Nginx/">Nginx</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Spring/">Spring</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringMVC/">SpringMVC</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/分布式/">分布式</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/日志管理/">日志管理</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/未分类/">未分类</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/03/">三月 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/01/">一月 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/10/">十月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/09/">九月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/08/">八月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/07/">七月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/06/">六月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/05/">五月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/04/">四月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/03/">三月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/02/">二月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/01/">一月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/12/">十二月 2015</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2017/03/13/docker-e5-be-ae-e6-9c-8d-e5-8a-a1-e5-ae-b9-e5-99-a8-e5-8c-96-e5-bc-80-e5-8f-91-e6-8e-a2-e7-b4-a2/">Docker-微服务容器化开发探索</a>
          </li>
        
          <li>
            <a href="/2017/01/20/drds-e7-bb-93-e5-90-88mybatis-e8-a7-a3-e5-86-b3-e6-96-b9-e6-a1-88-e4-b8-8e-e8-a7-84-e8-8c-83/">DRDS结合Mybatis解决方案与规范</a>
          </li>
        
          <li>
            <a href="/2017/01/03/springmvc-thymeleaf-e5-bc-80-e5-8f-91-e6-8c-87-e5-8d-97-demo/">SpringMVC-Thymeleaf-开发指南-Demo</a>
          </li>
        
          <li>
            <a href="/2016/10/16/nginx-e4-bb-a3-e7-90-86-e6-9c-8d-e5-8a-a1-e5-99-a8-e6-96-b9-e5-bc-8f-e8-a7-a3-e5-86-b3-e5-ae-9e-e9-99-85-e5-bc-80-e5-8f-91-e4-b8-adajax-e8-af-b7-e6-b1-82-e7-9a-84-e8-b7-a8-e5-9f-9f-e9-97-ae-e9-a2-98/">Nginx代理服务器方式解决实际开发中Ajax请求的跨域问题</a>
          </li>
        
          <li>
            <a href="/2016/10/11/e5-b7-a5-e5-8e-82-e6-a8-a1-e5-bc-8f-e5-92-8c-e5-8d-95-e4-be-8b-e6-a8-a1-e5-bc-8f-e7-bb-93-e5-90-88-e5-ba-94-e7-94-a8-e7-9a-84-e5-9c-ba-e6-99-af-e6-80-9d-e8-80-83/">工厂模式和单例模式结合应用的场景思考</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2017 Hank Chan<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>

  </div>
</body>
</html>